home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’93
/
OK, What was that again?
/
Extension
/
Backup
/
OK.c
next >
Wrap
C/C++ Source or Header
|
1993-06-17
|
11KB
|
429 lines
#include <Dialogs.h>
#include <GestaltEqu.h>
#ifndef __TYPES__
#include <Types.h>
#endif
#ifndef __MEMORY__
#include <Memory.h>
#endif
#ifndef __ERRORS__
#include <Errors.h>
#endif
#ifndef __TRAPS__
#include <Traps.h>
#endif
#ifndef __OSUTILS__
#include <OSUtils.h>
#endif
#ifndef __TOOLUTILS__
#include <ToolUtils.h>
#endif
#include <Resources.h>
#include <StdDef.h>
#include "OSUtilsSup.h"
#include "Icons.h"
pascal void ShowINIT(short iconID, short moveX);
pascal void MessageModalDialog(ModalFilterProcPtr filterProc,short *itemHit);
pascal OSErr MessageGestalt(OSType selector, long *response);
pascal Boolean MessageFilterProc(DialogPtr theDialog, EventRecord* theEvent, short* itemHit);
void foo(void);
void Globals(void);
pascal OSErr DetachIcon(ResType, Handle* theIcon, void*);
typedef pascal void (*TModalDialog)(ModalFilterProcPtr, short*);
typedef struct SLocals {
struct SLocals* oldLocals;
long ticks;
ModalFilterProcPtr filterProc;
short stage;
Boolean timedOut;
Rect mouseSlop;
GrafPort bwPort;
GrafPort colorPort;
Boolean isBWPort;
};
typedef struct SLocals SLocals;
struct SGlobals {
TModalDialog modalDialogProc;
SLocals* locals;
Handle iconSuites[6];
};
typedef struct SGlobals SGlobals;
void main(void)
{
SGlobals* globals = (SGlobals*)Globals;
Handle* iconSuite = &globals->iconSuites;
short i;
OSErr error;
THz zone;
QHdrPtr q = (QHdrPtr)foo;
q->qFlags = 0;
q->qHead = 0;
q->qTail = 0;
NewGestalt('Msg!',(ProcPtr)MessageGestalt);
(void)PatchTrap((ProcPtr*)&globals->modalDialogProc, _ModalDialog, (ProcPtr)MessageModalDialog, 0);
DetachResource(RecoverHandle((Ptr)main));
zone = GetZone();
SetZone(SystemZone());
for (i = 128; i <= 133; ++i) {
error = GetIconSuite(iconSuite, i, svAllLargeData);
error = ForEachIconDo(*iconSuite, svAllLargeData, (ProcPtr)DetachIcon, nil);
++iconSuite;
}
SetZone(zone);
ShowINIT(127,-1);
}
pascal OSErr DetachIcon(ResType, Handle* theIcon, void*)
{
if (*theIcon) DetachResource(*theIcon);
return noErr;
}
void Globals(void)
{
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
}
void foo(void)
{
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
}
pascal OSErr MessageGestalt(OSType, long *response)
{
*response = (long)foo;
return noErr;
}
typedef struct {
struct QElem *qLink; /* QElement header */
short qType;
PicHandle picture;
unsigned long dateTime;
Rect windowRect;
} Q;
enum {
fingerFromLeft = 7,
fingerFromTop = 10,
fingerSize = 32,
lastStage = 5, /* Dismiss Dialog when this stage is met */
secondsPerStage = 1, /* Time for each stage */
startTime = 60 * 5, /* Start to fade after n seconds */
delayTime = 60 * secondsPerStage, /* Delta between stages in n seconds */
slopAmount = 4 /* Reset when mouse moves by this */
};
pascal void MessageModalDialog(ModalFilterProcPtr filterProc,short *itemHit)
{
SGlobals* globals = (SGlobals*)Globals;
PicHandle picture;
GrafPtr theDialog;
THz zone;
Q* q;
GrafPtr oldPort;
QHdrPtr qHeader;
short itemType;
Handle handle;
Rect box, iconBox;
Str255 title;
SLocals locals;
Point mouse;
GetMouse(&mouse);
theDialog = FrontWindow();
GetDItem(theDialog, ok, &itemType, &handle, &box);
if (itemType != 4) goto bannana;
GetCTitle((ControlHandle)handle, title);
if (title[0] != 2) goto bannana;
if (title[1] != 'O') goto bannana;
if (title[2] != 'K') goto bannana;
if ((theDialog->portBits.rowBytes & 0xC000) != 0xC000) {
locals.isBWPort = true;
BlockMove(theDialog, &locals.bwPort, sizeof(GrafPort)); /* Make a copy of the Port */
GetPort(&oldPort);
OpenCPort((CGrafPtr)&locals.colorPort); /* Init a color Port */
/* Set up the color port to match the bw port */
PortSize(locals.bwPort.portRect.right - locals.bwPort.portRect.left,
locals.bwPort.portRect.bottom - locals.bwPort.portRect.top);
MovePortTo(- locals.bwPort.portBits.bounds.left, - locals.bwPort.portBits.bounds.top);
CopyRgn(locals.bwPort.visRgn, locals.colorPort.visRgn);
CopyRgn(locals.bwPort.clipRgn, locals.colorPort.clipRgn);
BlockMove(&locals.bwPort.pnLoc, &locals.colorPort.pnLoc, offsetof(GrafPort, pnPat) - offsetof(GrafPort, pnLoc));
BlockMove(&locals.bwPort.pnVis, &locals.colorPort.pnVis, sizeof(GrafPort) - offsetof(GrafPort, pnVis));
SetPort(oldPort);
} else {
locals.isBWPort = false;
}
locals.filterProc = filterProc;
locals.ticks = TickCount();
locals.timedOut = false;
locals.stage = 0;
locals.oldLocals = globals->locals;
SetRect(&locals.mouseSlop, mouse.h, mouse.v,
mouse.h, mouse.v);
InsetRect(&locals.mouseSlop, -slopAmount, -slopAmount);
globals->locals = &locals;
#define CallTheOldTrap (globals->modalDialogProc)
CallTheOldTrap(MessageFilterProc, itemHit);
globals->locals = locals.oldLocals;
if (locals.timedOut) {
GetPort(&oldPort);
SetPort(theDialog);
zone = GetZone();
SetZone(SystemZone());
picture = OpenPicture(&theDialog->portRect);
SetZone(zone);
InvalRect(&theDialog->portRect);
ClipRect(&theDialog->portRect);
/* If there is a filter proc then send it an update event to force any
additional drawing. */
if (filterProc) {
EventRecord theEvent = { updateEvt, (long)theDialog, TickCount(), { 0, 0 }, 0 };
(void)filterProc(theDialog, &theEvent, itemHit);
}
if (!EmptyRgn(((WindowPeek)theDialog)->updateRgn)) {
BeginUpdate(theDialog);
DrawDialog(theDialog);
EndUpdate(theDialog);
}
iconBox.left = ((box.left + box.right) >> 1) - fingerFromLeft;
iconBox.right = iconBox.left + fingerSize;
iconBox.top = ((box.top + box.bottom) >> 1) - fingerFromTop;
iconBox.bottom = iconBox.top + fingerSize;
ClipRect(&theDialog->portRect);
PlotIconSuite(&iconBox, atNone, ttNone, globals->iconSuites[lastStage]);
ClosePicture();
HiliteControl((ControlHandle)handle, 0);
q = (Q*)NewPtrSys(sizeof(Q));
q->picture = picture;
GetDateTime(&q->dateTime);
q->windowRect = theDialog->portRect;
LocalToGlobal((Point*)&q->windowRect.top);
LocalToGlobal((Point*)&q->windowRect.bottom);
if (Gestalt('Msg!', (long*)&qHeader) == noErr) Enqueue((QElemPtr)q, qHeader);
else {
DisposePtr((Ptr)q);
KillPicture(picture);
}
SetPort(oldPort);
*itemHit = ok;
}
if (locals.isBWPort) {
CloseCPort((CGrafPtr)&locals.colorPort);
}
return;
bannana:
CallTheOldTrap(filterProc, itemHit);
}
pascal Boolean MessageFilterProc(DialogPtr theDialog, EventRecord* theEvent, short* itemHit)
{
SGlobals* globals = (SGlobals*)Globals;
SLocals* locals = globals->locals;
short itemType;
Handle handle;
Rect box, iconBox;
GrafPtr currentPort;
if (((theEvent->what >= mouseDown) && (theEvent->what <= autoKey))
|| !PtInRect(theEvent->where, &locals->mouseSlop)) {
/* Brighten the control */
if (locals->stage != 0) {
RgnHandle firstMask = NewRgn();
RgnHandle secondMask = NewRgn();
GetDItem(theDialog, ok, &itemType, &handle, &box);
GetPort(¤tPort);
SetPort(theDialog);
iconBox.left = ((box.left + box.right) >> 1) - fingerFromLeft;
iconBox.right = iconBox.left + fingerSize;
iconBox.top = ((box.top + box.bottom) >> 1) - fingerFromTop;
iconBox.bottom = iconBox.top + fingerSize;
(void)IconSuiteToRgn(firstMask, &iconBox, atNone, globals->iconSuites[locals->stage - 1]);
if (locals->stage > lastStage) {
RectRgn(secondMask, &box);
UnionRgn(firstMask, secondMask, firstMask);
(*(ControlHandle)handle)->contrlHilite = 0;
}
InvalRgn(firstMask);
/* If there is a filter proc then send it an update event to force any
additional drawing. */
ClipRect(&theDialog->portRect);
EraseRgn(firstMask);
if (locals->filterProc) {
EventRecord theEvent = { updateEvt, (long)theDialog, TickCount(), { 0, 0 }, 0 };
(void)locals->filterProc(theDialog, &theEvent, itemHit);
}
if (!EmptyRgn(((WindowPeek)theDialog)->updateRgn)) {
BeginUpdate(theDialog);
DrawDialog(theDialog);
EndUpdate(theDialog);
}
DisposeRgn(firstMask);
DisposeRgn(secondMask);
SetPort(currentPort);
locals->stage = 0;
}
/* Reset the timer */
locals->ticks = TickCount();
/* Reset the mouseSlop */
SetRect(&locals->mouseSlop, theEvent->where.h, theEvent->where.v,
theEvent->where.h, theEvent->where.v);
InsetRect(&locals->mouseSlop, -slopAmount, -slopAmount);
} else if (locals->ticks + startTime + (locals->stage) * delayTime < TickCount()) {
if (locals->stage == 0) ObscureCursor();
if (locals->stage > lastStage) {
*itemHit = ok;
locals->timedOut = true;
return true;
} else {
RgnHandle firstMask = NewRgn();
RgnHandle secondMask = NewRgn();
GetDItem(theDialog, ok, &itemType, &handle, &box);
GetPort(¤tPort);
SetPort(theDialog);
iconBox.left = ((box.left + box.right) >> 1) - fingerFromLeft;
iconBox.right = iconBox.left + fingerSize;
iconBox.top = ((box.top + box.bottom) >> 1) - fingerFromTop;
iconBox.bottom = iconBox.top + fingerSize;
if (locals->stage != 0) {
(void)IconSuiteToRgn(firstMask, &iconBox, atNone, globals->iconSuites[locals->stage - 1]);
if (locals->stage == lastStage) {
RectRgn(secondMask, &box);
UnionRgn(firstMask, secondMask, firstMask);
(*(ControlHandle)handle)->contrlHilite = inButton;
}
(void)IconSuiteToRgn(secondMask, &iconBox, atNone, globals->iconSuites[locals->stage]);
DiffRgn(firstMask, secondMask, secondMask);
InvalRgn(secondMask);
/* If there is a filter proc then send it an update event to force any
additional drawing. */
ClipRect(&theDialog->portRect);
EraseRgn(secondMask);
if (locals->filterProc) {
EventRecord theEvent = { updateEvt, (long)theDialog, TickCount(), { 0, 0 }, 0 };
(void)locals->filterProc(theDialog, &theEvent, itemHit);
}
if (!EmptyRgn(((WindowPeek)theDialog)->updateRgn)) {
BeginUpdate(theDialog);
DrawDialog(theDialog);
EndUpdate(theDialog);
}
}
ClipRect(&theDialog->portRect);
if (locals->isBWPort) {
BlockMove(theDialog, &locals->bwPort, sizeof(GrafPort)); /* Blast back */
BlockMove(&locals->colorPort, theDialog, sizeof(GrafPort)); /* Blast in a color port */
}
PlotIconSuite(&iconBox, atNone, ttNone, globals->iconSuites[locals->stage]);
if (locals->isBWPort) {
BlockMove(&locals->bwPort, theDialog, sizeof(GrafPort)); /* Blast back */
}
DisposeRgn(firstMask);
DisposeRgn(secondMask);
SetPort(currentPort);
++locals->stage;
}
}
if (locals->filterProc) {
return locals->filterProc(theDialog, theEvent, itemHit);
} else return false;
}